<template>
  <div class="edit-menu">
    <a-modal
      :title="propsData.type === 'add' ? '新增角色' : '修改角色'"
      width="800px"
      :visible="visible"
      :confirm-loading="confirmLoading"
      :maskClosable="false"
      @ok="handleSubmit"
      @cancel="handleCancel"
    >
      <a-spin :spinning="spinning" tip="正在加载数据中...">
        <a-form :form="form" :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }">
          <a-form-item label="角色名称">
            <a-input
              v-decorator="[
                'RoleName',
                { rules: [{ required: true, message: '请输入角色名称', trigger: 'change' }] }
              ]"
              placeholder="请输入角色名称"
              autocomplete="off"
            />
          </a-form-item>
          <a-form-item label="备注">
            <a-textarea
              v-decorator="['Remark', { initialValue: '' }]"
              :auto-size="{ minRows: 3, maxRows: 5 }"
              placeholder="请输入备注"></a-textarea>
          </a-form-item>
          <a-form-item label="菜单权限">
            <a-card :bodyStyle="{padding: '10px', height: '300px', overflowY: 'auto'}">
              <template v-if="treeData.length > 0">
                <a-tree
                  checkable
                  :tree-data="treeData"
                  :checkedKeys="checkedKeys"
                  :replaceFields="{
                    title:'Title',
                    key:'ID',
                    children:'Children'
                  }"
                  @check="handleCheck"
                ></a-tree>
              </template>
              <template v-else>
                <a-empty />
              </template>
            </a-card>
          </a-form-item>
        </a-form>
      </a-spin>
    </a-modal>
  </div>
</template>

<script>
import cloneDeep from 'lodash.clonedeep'
import { setRoles, getRoleTrees, getRoleInfo } from '@/api/system'
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    propsData: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data () {
    return {
      confirmLoading: false,
      spinning: false,
      treeData: [],
      form: this.$form.createForm(this, { name: 'editRole' }),
      checkNodeList: [],
      checkedKeys: []
    }
  },
  watch: {
    propsData: function (newVal) {
      this.fetchRole()
    }
  },
  methods: {
    fetchRole () {
      const { propsData: { row, type } } = this
      this.spinning = true
      const tree = getRoleTrees({ userid: this.$store.getters.userid })
      const info = type === 'update' ? getRoleInfo({ ID: row.ID }) : {}
      Promise.all([ tree, info ]).then(res => {
        this.treeData = res[0].data
        if (type === 'add') return
        const { RoleName, Remark, Modulelist } = res[1].data
        const checkedKeysList = this.compareItem(Modulelist)
        this.$nextTick(function () {
          this.form.setFieldsValue({ RoleName, Remark })
          this.checkedKeys = checkedKeysList.halfChecked
          this.checkNodeList = checkedKeysList.checked
        })
      }).catch(() => {
        this.$message.error('网络请求失败, 请稍后重试')
      }).finally(() => {
        this.spinning = false
      })
    },
    // 获取角色信息时，回显菜单权限
    compareItem (list) {
      const checked = []
      const halfChecked = []
      const checkData = this.getTreeChildren(list)
      for (let i = 0; i < checkData.length; i++) {
        if (checkData[i].IsCheck) {
          checked.push(checkData[i].ID)
        }
        if (checkData[i].IsCheck && !checkData[i].isChild) {
          halfChecked.push(checkData[i].ID)
        }
      }
      return {
        checked,
        halfChecked
      }
    },
    // 树形数据转扁平化数据
    getTreeChildren (treeList) {
      const result = []
      treeList && treeList.map(item => {
        if (item.Children && item.Children.length > 0) {
          item.isChild = true
          result.push(...this.getTreeChildren(item.Children))
        } else {
          item.isChild = false
        }
        result.push(item)
      })
      return result
    },
    // 构造处理提交时菜单权限列表
    structureNode (node) {
      debugger
      const { getTreeChildren, treeData } = this
      const res = []
      const trees = getTreeChildren(cloneDeep(treeData))
      const childs = []
      for (const i in trees) {
        for (const j in node) {
          if (node[j] === trees[i].ID) {
            if (trees[i].Children === null && trees[i].PowerIdentifier === null) {
              childs.push(trees[i])
            } else {
              res.push({
                ID: trees[i].ID,
                Name: trees[i].Name,
                Title: trees[i].Title,
                PowerIdentifier: ''
              })
            }
          }
        }
      }
      res.forEach(i => {
        const temp = []
        childs.forEach(j => {
          if (i.ID === j.Pid) {
            temp.push(j.Name)
          }
          i.PowerIdentifier = temp.join()
        })
        return i
      })
      return res
    },
    handleCheck (checkedKeys, info) {
      this.checkedKeys = checkedKeys
      this.checkNodeList = checkedKeys.concat(info.halfCheckedKeys)
    },
    handleSubmit () {
      const { form: { validateFields }, propsData: { type, row }, $message, checkNodeList } = this
      validateFields((errors, values) => {
        if (!errors) {
          this.confirmLoading = true
          const submitData = Object.assign({}, values, {
            LoginName: this.$store.getters.nickname,
            UserID: this.$store.getters.userid,
            ModuleList: this.structureNode(checkNodeList)
          })
          if (type === 'update') {
            submitData.ID = row.ID
          }
          setRoles({
            State: type,
            quartersxq: submitData
          }).then((res) => {
            if (res.code === 200) {
              $message.success('提交成功', 3)
              this.handleCancel()
              this.$parent.$parent.$refs.table.refresh()
            } else {
              $message.error(res.msg, 3)
            }
          }).catch(() => {
            $message.error('提交失败', 3)
          }).finally(() => {
            this.confirmLoading = false
          })
        }
      })
    },
    handleCancel () {
      this.form.resetFields()
      this.treeData = []
      this.checkNodeList = []
      this.checkedKeys = []
      this.$emit('update:visible', false)
    }
  }
}
</script>
